home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectInput / DIConfig / cfrmwrk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  5.8 KB  |  241 lines

  1. //-----------------------------------------------------------------------------
  2. // File: cfrmwrk.cpp
  3. //
  4. // Desc: CDirectInputActionFramework is the outer-most layer of the UI. It
  5. //       contains everything else. Its functionality is provided by one
  6. //       method: ConfigureDevices.
  7. //
  8. //       InternalConfigureDevices is called by the CDirectInputActionFramework
  9. //       class. This function actually contains the initialization code and
  10. //       the message pump for the UI.
  11. //
  12. // Copyright (C) Microsoft Corporation. All Rights Reserved.
  13. //-----------------------------------------------------------------------------
  14.  
  15. #include "common.hpp"
  16.  
  17.  
  18. //QueryInterface
  19. STDMETHODIMP CDirectInputActionFramework::QueryInterface(REFIID iid, LPVOID* ppv)
  20. {
  21.     //null the out param
  22.     *ppv = NULL;
  23.  
  24.     if ((iid == IID_IUnknown) || (iid == IID_IDIActionFramework))
  25.     {
  26.         *ppv = this;
  27.         AddRef();
  28.         return S_OK;
  29.     }
  30.  
  31.     return E_NOINTERFACE;
  32. }
  33.  
  34.  
  35. //AddRef
  36. STDMETHODIMP_(ULONG) CDirectInputActionFramework::AddRef()
  37. {
  38.     return InterlockedIncrement(&m_cRef);
  39. }
  40.  
  41.  
  42. //Release
  43. STDMETHODIMP_(ULONG) CDirectInputActionFramework::Release()
  44. {
  45.     LONG cRef;
  46.     
  47.     cRef = InterlockedDecrement(&m_cRef);
  48.     if (cRef == 0)
  49.     {
  50.         delete this;
  51.     }
  52.  
  53.     return cRef;
  54. }
  55.  
  56. // Manages auto loading/unloading WINMM.DLL
  57. // There will only be one instance of this class: inside InternalConfigureDevicees.
  58. class CWinMmLoader
  59. {
  60. public:
  61.     CWinMmLoader()
  62.     {
  63.         if (!g_hWinMmDLL)
  64.         {
  65.             g_hWinMmDLL = LoadLibrary(_T("WINMM.DLL"));
  66.             if (g_hWinMmDLL)
  67.             {
  68.                 *(FARPROC*)(&g_fptimeSetEvent) = GetProcAddress(g_hWinMmDLL, "timeSetEvent");
  69.             }
  70.         }
  71.     }
  72.     ~CWinMmLoader()
  73.     {
  74.         if (g_hWinMmDLL)
  75.         {
  76.             /*
  77.              *  Make sure no new callbacks can get scheduled then sleep to 
  78.              *  allow any pending ones to complete.
  79.              */
  80.             g_fptimeSetEvent = NULL;
  81.             Sleep( 40 );
  82.             FreeLibrary(g_hWinMmDLL);
  83.             g_hWinMmDLL = NULL;
  84.         }
  85.     }
  86. };
  87.  
  88.  
  89.  
  90.  
  91. // internal, which api wraps around
  92. static HRESULT InternalConfigureDevices(LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
  93.                                         LPDICONFIGUREDEVICESPARAMSW  lpdiCDParams,
  94.                                         DWORD                        dwFlags,
  95.                                         LPVOID                       pvRefData)
  96. {
  97.  
  98.     CWinMmLoader g_WinMmLoadingHelper;  // Automatically call LoadLibrary and FreeLibrary on WINMM.DLL
  99.  
  100.     // check that we're at least 256 colors
  101.     HDC hMemDC = CreateCompatibleDC(NULL);
  102.     if (hMemDC == NULL)
  103.     {
  104.         etrace(_T("Can't get a DC! Exiting.\n"));
  105.         return E_FAIL;
  106.     }
  107.  
  108.     int bpp = GetDeviceCaps(hMemDC, BITSPIXEL);
  109.     DeleteDC(hMemDC);
  110.     if (bpp < 8)
  111.     {
  112.         etrace1(_T("Screen is not at least 8bpp (bpp = %d)\n"), bpp);
  113.         return E_FAIL;
  114.     }
  115.  
  116.     // do it...
  117.     {
  118.         // create the globals
  119.         CUIGlobals uig(
  120.             dwFlags,
  121.             lpdiCDParams->lptszUserNames,
  122.             lpdiCDParams->dwcFormats,
  123.             lpdiCDParams->lprgFormats,
  124.             &(lpdiCDParams->dics),
  125.             lpdiCDParams->lpUnkDDSTarget,
  126.             lpdiCallback,
  127.             pvRefData
  128.         );
  129.         HRESULT hr = uig.GetInitResult();
  130.         if (FAILED(hr))
  131.         {
  132.             etrace(_T("CUIGlobals.Init() failed\n"));
  133.             return hr;
  134.         }
  135.  
  136.         // make sure the flexwnd window class is registered only during possible use
  137.         {
  138.             struct flexwndscope {
  139.                 flexwndscope(CUIGlobals &uig) : m_uig(uig) {CFlexWnd::RegisterWndClass(m_uig.GetInstance());}
  140.                 ~flexwndscope() {CFlexWnd::UnregisterWndClass(m_uig.GetInstance());}
  141.                 CUIGlobals &m_uig;
  142.             } scope(uig);
  143.  
  144.             // create the main window
  145.             CConfigWnd cfgWnd(uig);
  146.             if (!cfgWnd.Create(lpdiCDParams->hwnd))
  147.             {
  148.                 etrace(_T("Failed to create main window\n"));
  149.                 return E_FAIL;
  150.             }
  151.  
  152.             // Initialize the shared tooltip object.
  153.             RECT rc = {0, 0, 0, 0};
  154.             CFlexWnd::s_ToolTip.Create(cfgWnd.m_hWnd, rc, TRUE);
  155.             if (!CFlexWnd::s_ToolTip.m_hWnd)
  156.             {
  157.                 etrace(_T("Failed to create tooltip window\n"));
  158.                 return E_FAIL;
  159.             }
  160.             ::ShowWindow(CFlexWnd::s_ToolTip.m_hWnd, SW_HIDE);  // Hide window by default
  161.  
  162.             // enter message loop
  163.             MSG msg;
  164.             while (GetMessage(&msg, NULL, 0, 0))
  165.             {
  166.                 // If this is a message for the parent window (game window), only dispatch if it's WM_PAINT.
  167.                 if (!cfgWnd.InRenderMode() && msg.hwnd == lpdiCDParams->hwnd && msg.message != WM_PAINT)
  168.                     continue;
  169.                 TranslateMessage(&msg);
  170.                 DispatchMessage(&msg);
  171.             }
  172.         }
  173.  
  174.         CFlexWnd::s_ToolTip.Destroy();
  175.  
  176.         return uig.GetFinalResult();
  177.     }
  178. }
  179.  
  180.  
  181. BOOL AreAcForsGood(LPDIACTIONFORMATW lpAcFors, DWORD dwNumAcFors)
  182. {
  183.     if (lpAcFors == NULL)
  184.         return FALSE;
  185.  
  186.     if (dwNumAcFors < 1)
  187.         return FALSE;
  188.  
  189.     if (lpAcFors->dwNumActions == 0)
  190.         return FALSE;
  191.  
  192.     return TRUE;
  193. }
  194.  
  195.  
  196. //ConfigureDevices
  197. STDMETHODIMP CDirectInputActionFramework::ConfigureDevices(
  198.             LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
  199.             LPDICONFIGUREDEVICESPARAMSW  lpdiCDParams,
  200.             DWORD                        dwFlags,
  201.             LPVOID                       pvRefData)
  202. {
  203.     // check parameters
  204.     if (lpdiCDParams == NULL)
  205.     {
  206.         etrace(_T("NULL params structure passed to ConfigureDevices()\n"));
  207.         return E_INVALIDARG;
  208.     }
  209.  
  210.     // save passed params in case we change 'em
  211.     LPDIACTIONFORMATW lpAcFors = lpdiCDParams->lprgFormats;
  212.     DWORD dwNumAcFors = lpdiCDParams->dwcFormats;
  213.  
  214.     HRESULT hr = InternalConfigureDevices(lpdiCallback, lpdiCDParams, dwFlags, pvRefData);
  215.  
  216.     // restore passed params in case changed
  217.     lpdiCDParams->lprgFormats = lpAcFors;
  218.     lpdiCDParams->dwcFormats = dwNumAcFors;
  219.  
  220.  
  221.     if (FAILED(hr))
  222.         etrace1(_T("ConfigureDevices() failed, returning 0x%08x\n"), hr);
  223.  
  224.     return hr;
  225. }
  226.  
  227.  
  228. //constructor
  229. CDirectInputActionFramework::CDirectInputActionFramework()
  230. {
  231.     //set ref count
  232.     m_cRef = 1;
  233. }
  234.  
  235.  
  236. //destructor
  237. CDirectInputActionFramework::~CDirectInputActionFramework()
  238. {
  239.     // not necessary to cleanup action format here
  240. }
  241.